/**
 * Copyright: Copyright (c)2011
 * Company: 易宝支付(YeePay)
 */
package net.loyintean.pearlshell.base.service.impl;

import java.io.IOException;

import net.loyintean.pearlshell.base.model.ILogInfo;
import net.loyintean.pearlshell.base.model.impl.LogInfoFactory;
import net.loyintean.pearlshell.base.service.HttpParseService;
import net.loyintean.pearlshell.base.service.HttpServiceNew;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.log4j.Logger;

/** 为post服务提供一个默认的实现类
 * <p>
 * 这个实现类是基于HttpClient-3.1编写的
 * 
 * @author：jun.lin@yeepay.com
 * @since：2015年3月13日 下午3:10:29
 * @version: */
public class HttpService4PostAbstract<T, E> implements HttpServiceNew<T, E> {

	/** LOGGER :日志记录器 */
	protected final Logger LOGGER = Logger.getLogger(this.getClass());

	/** parseService :参数解析服务 */
	private HttpParseService<T, E> parseService;

	/** httpclient :创建客户端
	 * <p>
	 * 为它声明一个多线程的连接管理器，以保证多线程安全性 */
	private final HttpClient httpclient = new HttpClient(
			new MultiThreadedHttpConnectionManager());

	/** url :请求发送的路径 */
	private String url;

	/** charset :编码格式
	 * <p>
	 * 默认为UT-8 */
	private String charset = "UTF-8";

	/** connectionTimeout : 连接超时时间
	 * <p>
	 * 单位是毫秒，默认是3000ms=3s */
	private int connectionTimeout = 3000;

	/** socketTimeout :socket读取时间
	 * <p>
	 * 单位是毫秒，默认是3000ms=3s */
	private int socketTimeout = 3000;

	/** initialized : 是否已初始化标志位。true为已初始化；fasle为未初始化 */
	private boolean initialized = false;

	/** 初始化方法。为 {@link #httpclient}设定编码格式
	 * <p>
	 * 可以用spring来设定初始化方法 */
	private void init() {
		if (!initialized) {

			httpclient.getParams().setParameter(
					HttpMethodParams.HTTP_CONTENT_CHARSET, charset);

			httpclient.getHttpConnectionManager().getParams()
					.setConnectionTimeout(connectionTimeout);

			httpclient.getHttpConnectionManager().getParams()
					.setSoTimeout(socketTimeout);

			initialized = true;
		}
	}

	/** @see com.yeepay.g3.core.onlinepayfee.utils.HttpService#send(RegisterDto) */
	@Override
	public final E send(T param) throws IOException {

		init();

		ILogInfo logInfo = LogInfoFactory.BUILD("service=" + toString()
				+ ",param=" + param);

		LOGGER.info(logInfo.start());

		// 创建调用方法
		PostMethod method = new PostMethod(url);

		parseService.generateRequestEntity(param, method);

		// 执行方法
		int statusCode = httpclient.executeMethod(method);

		if (statusCode != HttpStatus.SC_OK) {
			LOGGER.error(logInfo.error("statusCode=" + statusCode));
			throw new IOException(logInfo.error("statusCode=" + statusCode));
		}

		// 获取返回结果

		String returnString = method.getResponseBodyAsString();
		LOGGER.info(logInfo.inner("returnString=" + returnString));

		E result = parseService.parseResult(param, returnString);

		method.releaseConnection();

		LOGGER.info(logInfo.end("result=" + result));

		return result;
	}

	/** @param url
	 *            the url to set */
	public void setUrl(String url) {
		this.url = url;
	}

	/** @param charset
	 *            the charset to set */
	public void setCharset(String charset) {
		this.charset = charset;
	}

	/** @param connectionTimeout
	 *            the connectionTimeout to set */
	public void setConnectionTimeout(int connectionTimeout) {
		this.connectionTimeout = connectionTimeout;
	}

	/** @param socketTimeout
	 *            the socketTimeout to set */
	public void setSocketTimeout(int socketTimeout) {
		this.socketTimeout = socketTimeout;
	}

	/** @param parseService
	 *            the parseService to set */
	public void setParseService(HttpParseService<T, E> parseService) {
		this.parseService = parseService;
	}

	/** @param initialized
	 *            the initialized to set */
	public void setInitialized(boolean initialized) {
		this.initialized = initialized;
	}

}
